import Expression from "./interface/Expression";
import JoinExpression from "./JoinExpression";
import WhereExpression from "./WhereExpression";
import MetaData from "./MetaData";
import BaseExpression from "./abstract/BaseExpression";
import FieldExpression from "./impl/FieldExpression";

/** where表达式 */
class OnExpression extends BaseExpression {
    protected in: string;
    protected left: Expression;
    protected right: Expression;

    constructor(par: MetaData, left: string | Expression, right: string | Expression, inn: string = '=') {
        super(par);
        this.metadata.isOn = true;
        this.in = inn;
        this.left = typeof left === 'string' ? new FieldExpression(left, this.metadata) : left;
        this.right = typeof right === 'string' ? new FieldExpression(right, this.metadata) : right;
    }

    public static and(metaData: MetaData, left: string, right: string | Expression, inn: string = '=') {
        return new OnExpression(metaData, new FieldExpression(left, metaData.isOn ? "and" : "on", metaData), right, inn);
    }

    public static or(metaData: MetaData, left: string, right: string | Expression, inn: string = '=') {
        return new OnExpression(metaData, new FieldExpression(left, metaData.isOn ? "or" : "on", metaData), right, inn);
    }

    public toLocaSql(): string {
        return this.left.toLocaSql() + " " + this.in + " " + this.right.toLocaSql();
    }

    /** 删选语句 */
    public where(left: string, right: string | Expression, inn: string = '=') {
        if (right === undefined || right === null) {
            return this;
        }
        return WhereExpression.and(this.metadata, left, right, inn);
    }

    public orWhere(left: string, right: string | Expression, inn: string = '=') {
        return WhereExpression.or(this.metadata, left, right, inn);
    }

    public orOn(left: string, right: string | Expression, inn: string = '=') {
        return OnExpression.or(this.metadata, left, right, inn);
    }

    public on(left: string, right: string | Expression, inn: string = '=') {
        return OnExpression.and(this.metadata, left, right, inn);
    }

    /** 左连接查询 */
    public leftJoin(table: string, alias?: string) {
        return new JoinExpression(this.metadata, new FieldExpression(table, "left join", this.metadata), alias);
    }

    /** 右连接查询 */
    public rightJoin(table: string, alias?: string) {
        return new JoinExpression(this.metadata, new FieldExpression(table, "right join", this.metadata), alias);
    }

    /** 内连接查询 */
    public join(table: string, alias?: string) {
        return new JoinExpression(this.metadata, new FieldExpression(table, "join", this.metadata), alias);
    }
}

export = OnExpression;